package com.ins.service.impl;


import com.ins.common.exception.ServerException;
import com.ins.common.utils.InsUtils;
import com.ins.common.utils.Json;
import com.ins.common.utils.SecureUser;
import com.ins.mapper.AppRevenueMapper;
import com.ins.mapper.AppWalletMapper;
import com.ins.model.entity.AppWallet;
import com.ins.model.entity.AppWalletLog;
import com.ins.model.vo.AppWalletVO;
import com.ins.service.AppWalletService;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.data.id.IdUtil;
import org.dromara.hutool.core.text.StrUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Map;

import static com.ins.model.entity.table.AppRevenueTableDef.APP_REVENUE;
import static com.ins.model.entity.table.AppWalletTableDef.APP_WALLET;
import static com.mybatisflex.core.query.QueryMethods.sum;

/**
 * 钱包 服务层实现。
 *
 * @author ins
 * @since 2024-05-14
 */
@Service
@RequiredArgsConstructor
public class AppWalletServiceImpl extends ServiceImpl<AppWalletMapper, AppWallet> implements AppWalletService {

    private final AppRevenueMapper appRevenueMapper;

    @Override
    public AppWalletVO getInfo() {
        AppWalletVO vo = new AppWalletVO();
        AppWallet aw = this.getOne(APP_WALLET.USER_ID.eq(SecureUser.getUserId()));
        BeanUtil.copyProperties(aw, vo);

        Object todayMoney = appRevenueMapper.selectObjectByQuery(QueryWrapper.create().select(sum(APP_REVENUE.PRICE))
                                                                             .where(APP_REVENUE.USER_ID.eq(SecureUser.getUserId())));
        if (todayMoney != null) {
            vo.setTodayIncome(new BigDecimal(todayMoney.toString()));
        }

        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String withdrawals(Map<String, String> money) {
        String mny = money.get("money");
        if (StrUtil.isBlank(mny)) {
            throw ServerException.spe("请输入提现金额");
        }
        QueryWrapper queryWrapper = query().eq(APP_WALLET.USER_ID.getName(), SecureUser.getUserId()).forUpdate();
        AppWallet aw = this.getOne(queryWrapper);
        BigDecimal mnyDecimal = new BigDecimal(mny);
        if (mnyDecimal.compareTo(aw.getBalance()) > -1) {
            throw ServerException.spe("余额不足");
        }

        this.updateChain().set(APP_WALLET.BALANCE, APP_WALLET.BALANCE.subtract(mnyDecimal))
            .set(APP_WALLET.OUTCOME, APP_WALLET.OUTCOME.add(mnyDecimal))
            .where(APP_WALLET.USER_ID.eq(SecureUser.getUserId())).update();

        String beforeJson = Json.toStr(aw);
        BigDecimal subtract = aw.getBalance().subtract(mnyDecimal);
        aw.setBalance(subtract);
        aw.setOutcome(aw.getOutcome().add(mnyDecimal));
        String afterJson = Json.toStr(aw);
        long id = IdUtil.getSnowflakeNextId();
        String wlNo = InsUtils.getNoPrefix(InsUtils.WALLET_NO_PREFIX) + id;
        AppWalletLog awl = new AppWalletLog();
        awl.setUserId(SecureUser.getUserId());
        awl.setNo(wlNo);
        awl.setTargetType(2);
        awl.setActionType(2);
        awl.setFee(mnyDecimal);
        awl.setOriginalAccountJson(beforeJson);
        awl.setDisposeAccountJson(afterJson);
        awl.setStatus(0);
        awl.setId(id);
        awl.setCreateBy(SecureUser.getUserName());
        awl.setUpdateBy(SecureUser.getUserName());
        awl.setDeleted(0);
        awl.save();

        return "ok";
    }
}